package redisDB

import (
	"gitee.com/tsingeye/FreeEhome/config"
	"gitee.com/tsingeye/FreeEhome/tools/logs"
	"github.com/gomodule/redigo/redis"
)

var (
	redisPool *redis.Pool
)

func InitRedisDB() {
	redisPool = &redis.Pool{
		MaxIdle:     16,  //最大的空闲连接数，即使没有redis连接时依然可以保持N个空闲的连接，而不被清除，随时处于待命状态
		MaxActive:   32,  //最大的激活连接数，同时最多有N个连接
		IdleTimeout: 120, //空闲连接等待时间，超过此时间后，空闲连接将被关闭
		Dial: func() (conn redis.Conn, err error) {
			//return redis.Dial("tcp", config.RedisAddr)
			c, err := redis.Dial("tcp", config.RedisAddr)
			if err != nil {
				return nil, err
			}
			//无密码时不需要进行认证
			if config.RedisPass != "" {
				if _, err := c.Do("AUTH", config.RedisPass); err != nil {
					c.Close()
					return nil, err
				}
			}
			_, _ = c.Do("select", 0)
			return c, nil
		},
	}

	logs.BeeLogger.Emergency("init redis successful!!!")
}

//存储键值对。指定过期时间，单位秒
func SetEX(key, value interface{}, expiresAt int64) error {
	conn := redisPool.Get()
	defer conn.Close()

	switch expiresAt <= 0 {
	case true:
		//不设置过期时间
		_, err := conn.Do("SET", key, value)
		if err != nil {
			return err
		}
	default:
		//设置过期时间，单位秒
		_, err := conn.Do("SET", key, value, "EX", expiresAt)
		if err != nil {
			return err
		}
	}

	return nil
}

//根据键取值
func GetString(key interface{}) (string, error) {
	conn := redisPool.Get()
	defer conn.Close()

	return redis.String(conn.Do("GET", key))
}

func GetBytes(key interface{}) ([]byte, error) {
	conn := redisPool.Get()
	defer conn.Close()

	return redis.Bytes(conn.Do("GET", key))
}

//判断键是否存在
func Exists(key interface{}) bool {
	conn := redisPool.Get()
	defer conn.Close()

	isExists, err := redis.Bool(conn.Do("EXISTS", key))
	if err != nil {
		logs.BeeLogger.Error("key=%v, redis.Bool(redis.Do('EXISTS')) error:%s", key, err)
		return false
	}

	return isExists
}

//删除键值对，删除键值对时无需考虑该键值对是否存在，删除一个不存在的键值对不会报错
func Del(key interface{}) {
	conn := redisPool.Get()
	defer conn.Close()

	_, err := conn.Do("DEL", key)
	if err != nil {
		logs.BeeLogger.Error("redis.Do('DEL') error:%s", err)
	}
}

//重置键值对过期时间，单位秒
func Expire(key interface{}, expiresAt int64) {
	conn := redisPool.Get()
	defer conn.Close()

	_, err := conn.Do("EXPIRE", key, expiresAt)
	if err != nil {
		logs.BeeLogger.Error("redis.Do('EXPIRE') error:%s", err)
	}
}

//查询指定键的剩余过期时间，单位秒。返回值说明：
//-2：表示键过期且已删除
//-1：没有过期时间设置，即永不过期
//>0：表示距离过期还有多少秒
func TTL(key interface{}) int64 {
	conn := redisPool.Get()
	defer conn.Close()

	timeLeft, err := redis.Int64(conn.Do("TTL", key))
	if err != nil {
		logs.BeeLogger.Error("redis.Do('TTL') error:%s", err)
	}

	return timeLeft
}
